package com.nd.fastdp.file.service;

import cn.hutool.core.io.FileUtil;
import com.nd.fastdp.file.constant.ErrorCodeEnum;
import com.nd.fastdp.file.convert.NdFileConvert;
import com.nd.fastdp.file.dao.FileMapper;
import com.nd.fastdp.file.model.bo.FileBO;
import com.nd.fastdp.file.model.dto.FileAddParam;
import com.nd.fastdp.file.model.entity.NdFile;
import com.nd.fastdp.file.util.ResourceUtil;
import com.nd.fastdp.framework.exception.BusinessException;
import com.nd.fastdp.framework.pojo.constant.RespCodeEnum;
import com.nd.fastdp.framework.pojo.constant.StatusEnum;
import com.nd.fastdp.framework.pojo.dto.StateParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Auther: 刘畅
 * @Date: 2019-04-06 22:40
 * @Description: 附件业务处理类
 */
@Service
public class FileServiceImpl implements FileService{

    @Value("${fastdp.file.filepath}")
    public String tempPath;

    @Value("${fastdp.file.expireInterval}")
    public Long expireInterval;

    @Autowired
    private FileMapper fileMapper;

    @Transactional
    public FileBO add(FileAddParam param) {

        if (param.getFile() == null)
            throw new BusinessException(ErrorCodeEnum.UPLOAD_ISNULL_ERROR);

        File dest = null;

        try {

            String fileName = null;

            fileName = UUID.randomUUID().toString();

            LocalDate now = LocalDate.now();
            String dateStr = DateTimeFormatter.ofPattern("yyyy/MM/dd").format(now);
            //创建日期目录
            File directory = new File(ResourceUtil.getFilePath("") + tempPath + File.separator + dateStr);
            if (!directory.isDirectory())
                directory.mkdirs();

            dest = new File(directory.getPath() + File.separator + fileName);
            if (!dest.exists()) dest.createNewFile();

            FileUtil.writeBytes(param.getFile(), dest);

            NdFile ndFile = new NdFile();
            ndFile.setPath(File.separator + dateStr + File.separator + fileName);
            ndFile.setOriginalName(param.getOriginalFilename());
            ndFile.setState(StatusEnum.ENABLE.getValue());
            ndFile.setCreateTime(System.currentTimeMillis());

            fileMapper.insert(ndFile);

            return NdFileConvert.INSTANCE.to(ndFile);

        } catch (IOException e) {

            dest.delete();

            e.printStackTrace();

            throw new BusinessException(RespCodeEnum.INTERNAL_SERVER_ERROR);
        }
    }

    @Transactional
    public void updateBusId(String id, String busId, String type) {

        List<String> ids = new ArrayList<String>();

        ids.add(id);

        updateBusId(ids, busId, type);
    }

    @Override
    public void updateBusId(String id, String busId) {
        updateBusId(id, busId, NdFile.DEFAULT_TYPE);
    }

    @Transactional
    public void updateBusId(List<String> ids, String busId, String type) {

        Map<String, String> idMap = new HashMap<>();
        if(ids != null){
            for(String id : ids){
                idMap.put(id, id);
            }
        }

        List<NdFile> oldFiles = fileMapper.findByTypeAndBusinessId(type, busId);

        for(NdFile file: oldFiles){
            if(org.apache.commons.lang3.StringUtils.isEmpty(idMap.get(file.getId()))){
                fileMapper.unBindBusId(file.getId());
            }
        }

        if (ids == null || ids.size() <= 0) return;

        List<NdFile> ndFiles = fileMapper.selectBatchIds(ids);

        File file = null;

        for (NdFile ndFile : ndFiles) {

            if (!StringUtils.isEmpty(ndFile.getBusId())) continue;

            file = new File(ResourceUtil.getFilePath(tempPath + ndFile.getPath()));

            if (!file.exists())
                throw new BusinessException(ErrorCodeEnum.UPLOAD_INVALID_ERROR);

            ndFile.setBusId(busId);
            ndFile.setBusType(type);

            fileMapper.updateById(ndFile);

        }
    }

    @Override
    public void updateBusId(List<String> ids, String busId) {
        updateBusId(ids, busId, NdFile.DEFAULT_TYPE);
    }

    public void updateState(StateParam param) {

        fileMapper.updateState(param);
    }

    public void delByTypeAndBusId(String type, String busId) {

        fileMapper.delByTypeAndBusId(type, busId);
    }

    public List<FileBO> findByTypeAndBusId(String type, String busId) {

        List<NdFile> files = fileMapper.findByTypeAndBusinessId(type, busId);

        return NdFileConvert.INSTANCE.to(files);
    }

    public List<FileBO> findById(List<String> ids) {

        List<NdFile> files = fileMapper.selectBatchIds(ids);

        return NdFileConvert.INSTANCE.to(files);
    }

    public FileBO get(String id) {

        NdFile file = fileMapper.selectById(id);

        return NdFileConvert.INSTANCE.to(file);
    }

    @Override
    public File file(String id) {

        NdFile ndFile = fileMapper.selectById(id);

        File file = new File(tempPath + ndFile.getPath());

        return file;
    }

    @Override
    public byte[] fileStream(String id) {

        NdFile ndFile = fileMapper.selectById(id);

        File file = new File(tempPath + ndFile.getPath());

        return FileUtil.readBytes(file);
    }

    @Transactional
    public void clearTemp() {

        List<NdFile> ndFiles = fileMapper.findByTemp(System.currentTimeMillis() - expireInterval);

        File file = null;

        for (NdFile appendixFile : ndFiles) {

            file = new File(ResourceUtil.getFilePath(appendixFile.getPath()));

            if (file.exists()) file.delete();

            fileMapper.deleteById(appendixFile.getId());
        }
    }
}
